function getObjectFormArray(arr,id,pk){
	if(!pk)pk="id";
	for (var i = 0; i < arr.length; i++) {
		if(arr[i][pk] == id){
			return arr[i];
		}
	}
}
function SailsNgAdmin(option) {
	
	var admin = this;
	var app;
	var nga;
	
	this.config = option.config;
	
	this.entities = {};

	this.init = function() {
		var baseApiUrl = option.baseUrl + option.restPrefix + "/"
		var ngApp = angular.module('wechat-admin', [ 'ng-admin' ]);
		ngApp.controller('WechatCtrl', function($scope) {
			$scope.wxconfig = option;
		});

		ngApp.config([
			'NgAdminConfigurationProvider',
			'RestangularProvider',
			function(NgAdminConfigurationProvider,RestangularProvider) {
				
				nga = NgAdminConfigurationProvider;
				
				app = nga.application(option.title)
					.baseApiUrl(baseApiUrl)
					.debug(true);
				
				admin.configTransformer(RestangularProvider);
				admin.addEntities();
				admin.configEntities();
				admin.configHeader();
				admin.configMenu();
				
				nga.configure(app);
				
			}
		]);
		
		admin.configCustomPage(ngApp, '/form/:id', '/templates/form-detail.html', {}, function($scope,$stateParams,$http){
			var controller = this;
			var formId = $stateParams.id;
			var form = {};
			var formProps = {};
			var users = {};
			
			controller.baseUrl = option.baseUrl;
			
			$http.get(baseApiUrl + 'form/' + formId)
			.then(function (res) {
				form = res.data;
				return $http.get(baseApiUrl + 'form/' + formId + "/type");
			}).then(function(res){
				form.type = res.data;
				return $http.get(baseApiUrl + 'form/' + formId + "/propvals");
			}).then(function (res) {
				form.propvals = res.data;
				return $http.get(baseApiUrl + 'form/' + formId + "/attachments");
			}).then(function (res) {
				form.attachments = res.data;
				return $http.get(baseApiUrl + 'form/' + formId + "/opinions");
			}).then(function (res) {
				form.opinions = res.data;
				return $http.get(baseApiUrl + 'formprop');
			}).then(function (res) {
				formProps = res.data;
				return $http.get(baseApiUrl + 'user');
			}).then(function (res) {
				users = res.data;
				
				for (var i = 0; i < form.propvals.length; i++) {
					var propval = form.propvals[i];
					propval.prop = getObjectFormArray(formProps, propval.prop);
				}
				
				for (var i = 0; i < form.opinions.length; i++) {
					var opn = form.opinions[i];
					opn.superior = getObjectFormArray(users, opn.superior, 'userid');
				}
				
				form.state = FORM_STATES[form.state];
				form.owner = getObjectFormArray(users, form.owner, 'userid');
				controller.form = form;
				
			});
		});
	};
	
	this.configHeader = function(){
		$.ajax({
			url : option.baseUrl + '/templates/header.html',
			async : false,
			success : function(response,status,xhr){
				app.header(response);
			}
		});
	};
	
	this.configTransformer = function(RestangularProvider){
		RestangularProvider.addFullRequestInterceptor(
			function(element, operation, what, url, headers, params, httpConfig) {
				if (operation == 'getList') {
					if(params._page && params._perPage){
						params.skip = (params._page - 1) * params._perPage;
						params.limit = params._page * params._perPage;
						delete params._page;
						delete params._perPage;
					}
					if(params._sortField && params._sortDir){
						params.sort = params._sortField + ' ' + params._sortDir;
						delete params._sortField;
						delete params._sortDir;
					}
				}
				
				console.log("operation : " + operation);
				console.log("params : " + JSON.stringify(params));
				
				return { params: params };
			}
		);
		
		// add a response interceptor
		RestangularProvider.addResponseInterceptor(function(data, operation, what, url, response, deferred) {
			var extractedData;
			//to look for getList operations
			if (what === "leavenote") {
				if(operation === "getList" ){
					for (var i = 0; i < data.length; i++) {
						data[i].owner = data[i].form.owner;
						data[i].state = data[i].form.state;
					}
				}else if(operation === "get" ){
					data.owner = data.form.owner;
					data.state = data.form.state;
				}
			}
			if (operation === "getList" && what === "form") {
				var formData = [];
				for (var i = 0; i < data.length; i++) {
					if(data[i].type != option.noteType){
						formData.push(data[i]);
					}
				}
				data = formData;
			}
			if (what === "comment") {
				if(operation === "getList" ){
					for (var i = 0; i < data.length; i++) {
						data[i].postid = data[i].post;
					}
				}else if(operation === "get" ){
					data.postid = data.post;
				}
			}
			return data;
		});
	}
	
	this.configMenu = function(){
		app.menu(nga.menu()
			.addChild(nga.menu(this.entities['user']).title('用户管理').icon('<span class="ti-user"></span>'))
			.addChild(nga.menu(this.entities['department']).title('部门管理').icon('<span class="ti-home"></span>'))
			.addChild(
				nga.menu().title('报表管理').icon('<span class="ti-file"></span>')
				.addChild(nga.menu(this.entities['formtype']).title('报表类型').icon('<span class="ti-layers"></span>'))
				.addChild(nga.menu(this.entities['formprop']).title('报表属性').icon('<span class="ti-tag"></span>'))
				.addChild(nga.menu(this.entities['form']).title('报表').icon('<span class="ti-file"></span>'))
			)
			.addChild(
				nga.menu().title('请假管理').icon('<span class="ti-notepad"></span>')
				.addChild(nga.menu(this.entities['leavetype']).title('请假类型').icon('<span class="ti-layers"></span>'))
				.addChild(nga.menu(this.entities['leavenote']).title('请假条').icon('<span class="ti-clipboard"></span>'))
				.addChild(nga.menu(this.entities['vacation']).title('年假').icon('<span class="ti-clipboard"></span>'))
			)
			.addChild(
				nga.menu().title('同事圈').icon('<span class="ti-world"></span>')
				.addChild(nga.menu(this.entities['post']).title('文章管理').icon('<span class="ti-book"></span>'))
				.addChild(nga.menu(this.entities['comment']).title('评论管理').icon('<span class="ti-comment-alt"></span>'))
			)
			.addChild(
				nga.menu(this.entities['news']).title('新闻公告').icon('<span class="ti-world"></span>')
			)
			.addChild(
				nga.menu().title('安装').icon('<span class="ti-thought"></span>').link('/install')
			)
		);
	}
	
	this.configCustomPage = function(ngApp, path, tmplPath, params, ctrl){
		$.ajax({
			url : option.baseUrl + tmplPath,
			async : false,
			success : function(response,status,xhr){
				ngApp.config(['$stateProvider', function ($stateProvider) {
					$stateProvider.state('stats', {
						parent: 'main',
						url: path,
						params: params,
						controller : ctrl,
						controllerAs: 'controller',
						template: response
					});
				}]);
			}
		});
		
	};
	
	this.addEntities = function(){
		for ( var entity in this.config) {
			var ent = nga.entity(entity);
			this.entities[entity] = ent;
			
			var entCfg = this.config[entity];
			if(entCfg.identifier){
				ent = ent.identifier(nga.field(entCfg.identifier));
			}
			app.addEntity(ent);
		}
	}
	
	this.configEntities = function(){
		for ( var entity in this.entities) {
			var ent = this.entities[entity];
			var entCfg = this.config[entity];
			
			if(entCfg.create){
				var ctview = this.commonView(ent, entCfg, 'create');
				this.createView(ent, entCfg, ctview);
			}
			
			if(entCfg.list){
				var lsview = this.commonView(ent, entCfg, 'list');
				this.listView(ent, entCfg, lsview);
			}
			
			if(entCfg.show){
				var shview = this.commonView(ent, entCfg, 'show');
				this.showView(ent, entCfg, shview);
			}
			
			if(entCfg.delete){
				var delview = this.commonView(ent, entCfg, 'delete');
				this.deleteView(ent, entCfg, delview);
			}
			
			if(entCfg.edit){
				var edview = this.commonView(ent, entCfg, 'edit');
				this.editView(ent, entCfg, edview);
			}
			
			if(entCfg.dashboard){
				var dshview = this.commonView(ent, entCfg, 'dashboard');
				this.dashboardView(ent, entCfg, dshview);
			}
			
		}
	};
	
	this.getFields = function(cfg,type,entity,expt){
		var fields = [];
		var fieldsArr = [];
		var cfgFields = cfg.fields;
		
		if(cfg[type] != undefined && cfg[type].fields != undefined){
			if(expt){
				fieldsArr = cfg[type].exportFields;
			}else{
				fieldsArr = cfg[type].fields;
			}
		}
		
		for (var i = 0; i < fieldsArr.length; i++) {
			var fieldType = 'string';
			var target = cfgFields[fieldsArr[i]].target;
			var template = cfgFields[fieldsArr[i]].template;
			var map = cfgFields[fieldsArr[i]].map;
			var detailLink = cfgFields[fieldsArr[i]].detailLink;
			var isDetailLink = cfgFields[fieldsArr[i]].isDetailLink;
			
			if(cfgFields[fieldsArr[i]].type != undefined){
				fieldType = cfgFields[fieldsArr[i]].type;
			}else if(template){
				fieldType = 'template';
			}
			
			var fld = nga.field(fieldsArr[i], fieldType).label(cfgFields[fieldsArr[i]].label);
			
			if(target){
				if(target.entity){
					fld = fld.targetEntity(this.entities[target.entity]);
				}
				
				if(target.field){
					fld = fld.targetField(nga.field(target.field));
				}
				
				if(target.refField){
					fld = fld.targetReferenceField(target.refField);
				}
				
				if(target.fields){
					//fld = fld.targetReferenceField(target.refField);
					
					/*var refFields = NgAdminConfig[entity._name].fields;
					var refFieldsArr = [];
					
					for (var j = 0; j < target.fields.length; j++) {
						refFieldsArr.push(nga.field(target.fields[j]).label(refFields[target.fields[j]].label));
					}
					fld = fld.targetFields(refFieldsArr);*/
					
				}
			}
			
			if(detailLink){
				fld = fld.detailLinkRoute(detailLink);
			}else{
				fld = fld.detailLinkRoute("show");
			}
			
			if(isDetailLink != undefined){
				fld = fld.isDetailLink(isDetailLink);
			}
			
			if(template){
				fld = fld.template(template);
			}
			
			if(map){
				fld = fld.map(map);
			}
			
			fields.push(fld);
		}
		
		return fields;
	};
	
	this.dashboardView = function(entity, cfg, view){
		
		if(view == null || cfg.dashboard == undefined)
			return ;
		
		if(cfg.dashboard.sortField){
			view = view.sortField(cfg.dashboard.sortField);
		}
		
		if(cfg.dashboard.sortDir){
			view = view.sortDir(cfg.dashboard.sortDir);
		}
		
		if(cfg.dashboard.perPage){
			view = view.perPage(cfg.dashboard.perPage);
		}
		
		if(cfg.dashboard.order){
			view = view.order(cfg.dashboard.order);
		}
		
	};
	
	this.createView = function(entity, cfg, view){
		
		if(view == null)
			return ;
		
		view = view.actions("<ma-list-button entity='entity' label='列表' ></ma-list-button>");
	};
	
	this.editView = function(entity, cfg, view){
		
		if(view == null)
			return ;
		
		view = view.actions("<ma-list-button entity='entity' label='列表' ></ma-list-button>");
	};
	
	this.deleteView = function(entity, cfg, view){
		
		if(view == null)
			return ;
		
		view = view.actions("<ma-list-button entity='entity' label='列表' ></ma-list-button>");
	};
	
	this.showView = function(entity, cfg, view){
	
		if(view == null)
			return ;
		
		view = view.actions("<ma-list-button entity='entity' label='列表' ></ma-list-button>");
		
	};
	
	this.listView = function(entity, cfg, view){
		
		if(view == null)
			return ;

		view = view.infinitePagination(false);
		
		if(cfg.list.sortField){
			view = view.sortField(cfg.list.sortField);
		}
		
		if(cfg.list.sortDir){
			view = view.sortDir(cfg.list.sortDir);
		}
		
		if(cfg.list.exportFields){
			view = view.exportFields(this.getFields(cfg, 'list', entity, true));
		}
		
		if(cfg.list.listActions){
			var template = "";
			for (var i = 0; i < cfg.list.listActions.length; i++) {
				if(cfg.list.listActions[i] == 'edit'){
					template += '<ma-edit-button entry="entry" entity="entity" label="编辑" size="xs"></ma-edit-button> ';
				}else if(cfg.list.listActions[i] == 'delete'){
					template += '<ma-delete-button entry="entry" entity="entity" label="删除" size="xs"></ma-delete-button> ';
				}else if(cfg.list.listActions[i] == 'show'){
					template += '<ma-show-button entry="entry" entity="entity" label="详细" size="xs"></ma-show-button> ';
				}
			}
			//view = view.fields([nga.field('操作', 'template').template(template)]);
			view = view.listActions(template);
		}
		
		
		/*
		nga.field('props', 'reference_many')
			.targetEntity(formprop)
			.targetField(nga.field('formType'))*/
		
		//return view;
	};
	
	this.commonView = function(entity, cfg, type){
		
		var view = null;
		var commonCfg = cfg[type];
		
		if(commonCfg == undefined){
			return view;
		}
		
		if(type == 'create'){
			view = entity.creationView().fields(this.getFields(cfg, 'create', entity));
		}else if(type == 'show'){
			view = entity.showView().fields(this.getFields(cfg, 'show', entity));
		}else if(type == 'list'){
			view = entity.listView().fields(this.getFields(cfg, 'list', entity));
		}else if(type == 'delete'){
			view = entity.deletionView().fields(this.getFields(cfg, 'delete', entity));
		}else if(type == 'edit'){
			view = entity.editionView().fields(this.getFields(cfg, 'edit', entity));
		}else if(type == 'dashboard'){
			view = entity.dashboardView().fields(this.getFields(cfg, 'dashboard', entity));
		}
		
		if(commonCfg.title){
			view = view.title(commonCfg.title)
		}
		
		if(commonCfg.description){
			view = view.description(commonCfg.description)
		}
		
		if(commonCfg.url){
			view = view.url(commonCfg.url)
		}
		
		if(commonCfg.actions){
			var template = "";
			for (var i = 0; i < commonCfg.actions.length; i++) {
				if(commonCfg.actions[i] == 'export'){
					template += '<ma-export-to-csv-button entity="entity" search="search" datastore="datastore" label="导出"></ma-export-to-csv-button> ';
				}else if(commonCfg.actions[i] == 'create'){
					template += '<ma-create-button entity="entity" label="新建"></ma-create-button> ';
				}
				
			}
			view = view.actions(template);
		}
		
		if(commonCfg.custom){
			view = commonCfg.custom(entity, cfg, view);
		}
		
		return view;
		
	};
	
	this.init();

}